package cn.itcast.up.up_web.service.impl;

import cn.itcast.up.up_web.bean.dto.ModelDto;
import cn.itcast.up.up_web.bean.dto.TagDto;
import cn.itcast.up.up_web.bean.dto.TagModel;
import cn.itcast.up.up_web.bean.po.ModelPo;
import cn.itcast.up.up_web.bean.po.TagPo;
import cn.itcast.up.up_web.repo.ModelRepository;
import cn.itcast.up.up_web.repo.TagRepository;
import cn.itcast.up.up_web.service.TagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TagServiceImpl implements TagService {

    //导入tagrepo
    @Autowired
    private TagRepository tagRepository;

    //引入模型的Repo
    @Autowired
    private ModelRepository modelRepository;


    @Override
    public void saveAll(List<TagDto> list) {
        //将123级标签数据保存起来.

        //我们需要将TagDto -> tagPo

        //方案1: 使用循环
        /*for (TagDto tagDto : list) {
            //开始转换
            TagPo tagPo = new TagPo();
            tagPo.setId(tagDto.getId());
        }*/
        //优化:
        /*for (TagDto tagDto : list) {
            //开始转换
            convert(tagDto);
        }*/
        //方案2:
        /*List<TagPo> tempList = list.stream().map((dto) -> {
            return convert(dto);
        }).collect(Collectors.toList());*/

        //方案3: 使用list的流将数据从dto转换为po类型
        List<TagPo> poList = list.stream().map(this::convert).collect(Collectors.toList());

        //将集合中的数据提取出来,然后进行保存.
        TagPo tag1 = poList.get(0);
        TagPo tag2 = poList.get(1);
        TagPo tag3 = poList.get(2);

        //先保存1级标签,设置父ID为-1
        tag1.setPid(-1L);
        //先判断有没有这个1级的标签, 同级别,同名字,同父ID
        /*金融
                人口属性
                人口属性
        电商
                人口属性*/

        //看有没有重复
        TagPo tmpTag = tagRepository.findByLevelAndNameAndPid(tag1.getLevel(), tag1.getName(), tag1.getPid());
        if (tmpTag == null){
            //没找到,那么就将这个临时的tag进行赋值
            tmpTag = tagRepository.save(tag1);
        }
        //获取到1级标签的id,作为2级标签的父ID
        tag2.setPid(tmpTag.getId());
        //保存2级
        //看有没有重复
        tmpTag = tagRepository.findByLevelAndNameAndPid(tag2.getLevel(), tag2.getName(), tag2.getPid());
        if (tmpTag == null){
            //没找到,那么就将这个临时的tag进行赋值
            tmpTag = tagRepository.save(tag2);
        }
        //获取到2级标签的id,作为3级标签的父ID
        tag3.setPid(tmpTag.getId());
        //保存3级.
        tmpTag = tagRepository.findByLevelAndNameAndPid(tag3.getLevel(), tag3.getName(), tag3.getPid());
        if (tmpTag == null){
            //没找到,那么就将这个临时的tag进行赋值
            tmpTag = tagRepository.save(tag3);
        }
    }

    @Override
    public List<TagDto> findTagsByPid(Long pid) {
        //根据Pid查询对应的标签并返回
        List<TagPo> poList = tagRepository.findByPid(pid);
        //将po集合转换为dto集合
        return poList.stream().map(this::convert).collect(Collectors.toList());
    }

    @Override
    public void saveTagModel(TagModel tagModel) {
        //保存4级标签数据,然后获取它的4级ID
        TagPo saveTag = tagRepository.save(convert(tagModel.getTag()));
        //保存的模型数据,设置标签的ID
        ModelDto model = tagModel.getModel();
        modelRepository.save(convert(model, saveTag.getId()));
    }

    /**
     * 根据ID查询所有的4级标签数据和模型
     * @param pid 3级标签的ID
     * @return
     */
    @Override
    public List<TagModel> findAllTagModel(Long pid) {
        ArrayList<TagModel> tagModels = new ArrayList<>();
        //目前过来的标签ID是3级,但后面有可能会过来4级,所以我们需要进行一些处理,
        //防止过来的是4级的时候,查询5级的模型,会查询失败.
        //先根据3级ID查询4级,(也有可能是查询5级)
        List<TagPo> tagList = tagRepository.findByPid(pid);
        //使用循环开始遍历
        for (TagPo tagPo : tagList) {
            ModelPo modelPo = null;
            //先判断当前的tagPo是4级还是5级
            //如果是4级,就获取模型
            if (tagPo.getLevel() == 4) {
                //获取模型
                Long tagID = tagPo.getId();
                modelPo = modelRepository.findByTagId(tagID);
            } else {
            //如果是5级,模型置为空
            }

            tagModels.add(new TagModel(convert(tagPo), convert(modelPo)));
        }
        return tagModels;
    }

    //保存5级规则数据
    @Override
    public void addDataTag(TagDto tagDto) {
        tagRepository.save(convert(tagDto));
    }



    //将模型的po->dto
    private ModelDto convert(ModelPo modelPo) {
        if (modelPo == null) {
            return null;
        }
        return new ModelDto(
                modelPo.getId(),
                modelPo.getName(),
                modelPo.getMainClass(),
                modelPo.getPath(),
                modelPo.getArgs(),
                //如果不是用构造方式,可以先new一个modelDto,然后用对象来调用
                ModelDto.parseDate(modelPo.getSchedule()),
                modelPo.getState()
                );
    }

    //将模型的dto->po
    private ModelPo convert(ModelDto model, Long id) {
        return new ModelPo(null,id, model.getName(), model.getState(), model.getPath(),
                model.getMainClass(),
                //我们需要调用toPattern将时间转换为字符串
                model.getSchedule().toPattern(),
                model.getArgs(),
                new Date(), new Date());
    }

    /**
     * 将标签的po对象转换为dto对象
     * @param po
     * @return
     */
    private TagDto convert(TagPo po){
        return new TagDto(po.getId(), po.getName(), po.getRule(), po.getLevel(), po.getPid(), po.getState(), po.getBusiness());
    }

    /**
     * 将标签的dto对象转换为po对象
     * @param dto
     * @return
     */
    private TagPo convert(TagDto dto){
        TagPo po = new TagPo();
        po.setId(dto.getId());
        po.setName(dto.getName());
        po.setRule(dto.getRule());
        po.setLevel(dto.getLevel());
        po.setPid(dto.getPid());
        po.setState(dto.getState());
        po.setBusiness(dto.getBusiness());
        return po;
    }
}
